package bgapi

import (
	"bgs/db"
	sqlc "bgs/db/sqlc"
	userService "bgs/service/user"
	"bgs/util"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
)

var (
	lastUserFanMessage *UserFanMessage = nil
)

// UserFanMessage UserFan message struct
type UserFanMessage struct {
	TS   int64 `json:"ts"`
	Data struct {
		// 被关注用户id
		UserID int64 `json:"user_id"`
		// 作为粉丝的用户id
		FollowerUserID int64 `json:"follower_user_id"`

		// 被关注时间
		BeFollowed int64 `json:"be_followed"`

		// 默认用user.nick_name
		AliasName string `json:"alias_name"`
	} `json:"data"`
}

// UserFanHandler UserFan message handler
type UserFanHandler struct {
	dao         *db.PgDao
	slog        *zap.SugaredLogger
	userService *userService.UserServiceImp
}

// NewUserFanHandler create a new handler for UserFan
func NewUserFanHandler(
	pgdao *db.PgDao,
	slog *zap.SugaredLogger,
	userService *userService.UserServiceImp,
) *UserFanHandler {
	return &UserFanHandler{
		dao:         pgdao,
		slog:        slog.With("module", "UserFanHandler"),
		userService: userService,
	}
}

// HandleMessage implements the Handler interface.
func (h *UserFanHandler) HandleMessage(m *nsq.Message) error {
	if len(m.Body) == 0 {
		// Returning nil will automatically send a FIN command to NSQ to mark the message as processed.
		return nil
	}

	h.slog.Infof("UserFanMessage=>%s", string(m.Body))

	v := &UserFanMessage{}
	if decodeErr := json.NewDecoder(bytes.NewReader(m.Body)).Decode(v); decodeErr != nil {
		return fmt.Errorf("无法解析信息[UserFanMessage]: %v", decodeErr)
	}
	if lastUserFanMessage != nil && lastUserFanMessage.TS >= v.TS {
		h.slog.Infof("过时的消息: lastUserFanMessage.TS:%v,v.TS:%v", lastUserFanMessage.TS, v.TS)
		return nil
	}

	ctx := context.Background()
	userID := v.Data.UserID
	
	err := h.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		_, err = q.UpsertUserFan(ctx, sqlc.UpsertUserFanParams{
			UserID:         userID,
			FollowerUserID: v.Data.FollowerUserID,
			BeFollowed:     util.MsToGoTime(v.Data.BeFollowed),
			AliasName:      v.Data.AliasName,
		})
		if err != nil {
			return err
		}
		h.slog.Infof("a UserFanHandler-插入/更新用户粉丝关系 ok")
		err = h.userService.UpdateUserStatSinceBeFollowed(ctx, q, userID)
		if err != nil {
			return err
		}
		h.slog.Infof("b UserFanHandler-用户被关注统计到(UserStat) ok")
		return
	})

	if err != nil {
		return err
	}
	lastUserFanMessage = v
	// Returning a non-nil error will automatically send a REQ command to NSQ to re-queue the message.
	return nil
}
